// TMap.cpp: implementation of the TMap class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
//#include "TNM.h"
#include "TMap.h"
//#include "TSetMap.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

TMap::TMap()
: m_fZoom(1.0f)
, m_hBMdis((HBITMAP)INVALID_HANDLE_VALUE)
, m_hBMsrc((HBITMAP)INVALID_HANDLE_VALUE)
{
	m_DCdis.CreateCompatibleDC(NULL);
	m_navigate.m_map = this;

	UpdateSettings();
}

TMap::~TMap()
{
	m_DCdis.DeleteDC();
	m_DCsrc.DeleteDC();
	
	DeleteObject(m_hBMsrc);
	m_hBMsrc = (HBITMAP)INVALID_HANDLE_VALUE;
	
	DeleteObject(m_hBMdis);
	m_hBMdis = (HBITMAP)INVALID_HANDLE_VALUE;
}

void TMap::UpdateSettings()
{
	if (NULL != m_navigate.GetSafeHwnd())
		m_navigate.UpdateSize();

	//CTNMApp *papp = (CTNMApp*)AfxGetApp();
	//
	//int times;
	//
	//times = papp->GetProfileInt(TSetMap::ikey_MaxZoom, -1);
	//max_zoom = times > 0 ? times : 16.0f;

	//times = papp->GetProfileInt(TSetMap::ikey_MinZoom, -1);
	//min_zoom = times > 0 ? 1.0f / times : 1.0f / 16.0f;
	//
	//times = papp->GetProfileInt(TSetMap::ikey_SpeedZoom, -1);
	//m_off = times > 0 ? times / 32.0f : 0.9375f;


	max_zoom = 16.0f;

	min_zoom = 1.0f / 16.0f;

	m_off =  0.9375f;

}

void TMap::Draw(CDC *pDC)
{
	pDC->BitBlt(
		0,
		0,
		m_sizeDis.cx,
		m_sizeDis.cy,
		&m_DCdis,
		0,
		0,
		SRCCOPY);
}

BOOL TMap::ZoomIn()
{
	if (m_fZoom < min_zoom)
	{
		return FALSE;
	}

	m_fZoom *= m_off;
	UpdateMap();

	return TRUE;
}

BOOL TMap::ZoomOut()
{
	if (m_fZoom > max_zoom)
	{
		return FALSE;
	}

	m_fZoom /= m_off;
	UpdateMap();

	return TRUE;
}

//move PTcenter by zoom
// float + 0.5f round covert to int
void TMap::BeginMove(CPoint *point)
{
	point->x = (int)(point->x * m_fZoom + 0.5f);
	point->y = (int)(point->y * m_fZoom + 0.5f);

	m_ptCenter += *point;
}

void TMap::EndMove(CPoint *point)
{
	point->x = (int)(point->x * m_fZoom + 0.5f);
	point->y = (int)(point->y * m_fZoom + 0.5f);

	m_ptCenter -= *point;
	UpdateMap();
}

void TMap::UpdateSize(CSize *size)
{
	if (NULL != size)
	{
		m_sizeDis = *size;
	}

	//rectView.center = rectBitmap.center
	//sizeView = sizeBitmap * zoom
	m_rcView.top	= (int)(m_ptCenter.y - m_sizeDis.cy * m_fZoom / 2 + 0.5f);
	m_rcView.left	= (int)(m_ptCenter.x - m_sizeDis.cx * m_fZoom / 2 + 0.5f);
	m_rcView.right	= (int)(m_ptCenter.x + m_sizeDis.cx * m_fZoom / 2 + 0.5f);
	m_rcView.bottom	= (int)(m_ptCenter.y + m_sizeDis.cy * m_fZoom / 2 + 0.5f);
 
 	DeleteObject(m_hBMdis);
 	m_hBMdis = CreateCompatibleBitmap(::GetDC(NULL), m_sizeDis.cx, m_sizeDis.cy);

	m_DCdis.SelectObject(m_hBMdis);
 	m_DCdis.StretchBlt(
 		0,
 		0,
 		m_sizeDis.cx,
 		m_sizeDis.cy,
 		&m_DCsrc,
 		m_rcView.left,
 		m_rcView.top,
 		m_rcView.Width(),
 		m_rcView.Height(),
 		SRCCOPY);
}

BOOL TMap::LoadMapFromPicture(LPCTSTR filePath)
{
	CString cs(filePath);

	if (NULL == filePath)
	{
		//cs = ((CTNMApp*)AfxGetApp())->GetProfileString(TSetMap::skey_MapFile);
	}

	CFile filePicture;
	BOOL bIsOK = FALSE;
	int nLen = 0x00;

	try
	{
		bIsOK = filePicture.Open(cs, CFile::modeRead);
		if(	bIsOK )
		{
			nLen =  (int)filePicture.GetLength();
		}else
		{
			AfxMessageBox(CString("Open bitmap file Failed") + cs);
		}
	}
	catch (...)
	{
		return FALSE;
	}
	
	BYTE *buf = new BYTE[nLen];
	if (NULL == buf)
	{
		return FALSE;
	}
	
	DWORD dwRead = (DWORD)filePicture.Read(buf, filePicture.GetLength());
	if (dwRead != filePicture.GetLength())
	{
		delete[] buf;
		buf = NULL;
		return FALSE;
	}
	
	BITMAPFILEHEADER *bmfh = (BITMAPFILEHEADER*)buf;
	BITMAPINFOHEADER *bmih = (BITMAPINFOHEADER*)(buf + sizeof(BITMAPFILEHEADER));
	
	DeleteObject(m_hBMsrc);
	m_hBMsrc = ::CreateDIBitmap(
		::GetDC(NULL), 
		bmih, 
		CBM_INIT, 
		buf + bmfh->bfOffBits, 
		(BITMAPINFO*)bmih, 
		DIB_RGB_COLORS);
	
	m_DCsrc.DeleteDC();
	m_DCsrc.CreateCompatibleDC(NULL);
	m_DCsrc.SelectObject(m_hBMsrc);

	m_ptCenter.x = bmih->biWidth / 2;
	m_ptCenter.y = bmih->biHeight / 2;

	delete[] buf;
	buf = NULL;
	
	return TRUE;
}

void TMap::UpdateMap()
{
	UpdateSize(NULL);
	UpdateCross();
}

//void TMap::CreateCross(HWND view, TCrossWnd *pcw)
//{
//	CPoint pt = MpToVp(pcw->m_ptOffset);
//	
//	pcw->CreateEx(
//		WS_EX_WINDOWEDGE,
//		TCrossWnd::static_lpctstrClassName,
//		pcw->m_sName,
//		WS_VISIBLE | WS_CHILD | WS_BORDER,
//		pt.x,
//		pt.y,
//		48, 
//		48+HIWORD(GetDialogBaseUnits()), 
//		view,
//		0);
//}

void TMap::UpdateCross()
{
	//for (int i=0; i<TCrossWnd::static_apCrossWnd.GetSize(); ++i)
	//{
	//	//TCrossWnd *pcw = TCrossWnd::static_apCrossWnd[i];
	//	//
	//	//if (m_rcView.PtInRect(pcw->m_ptOffset))
	//	//{
	//	//	CPoint x = MpToVp(pcw->m_ptOffset);
	//	//	
	//	//	pcw->MoveWindow(
	//	//		x.x,
	//	//		x.y,
	//	//		48,
	//	//		48 + HIWORD(GetDialogBaseUnits()));
	//	//	
	//	//	//pcw->ShowWindow(SW_NORMAL);
	//	//}
	//	//else
	//	//{
	//	//	//pcw->ShowWindow(SW_HIDE);
	//	//}
	//}
}

CPoint TMap::MpToVp(const CPoint &mp)
{
	//pointView = centerView - (centerMap - pointMap) / zoom
	//centerView = sizeView / 2
	
	CPoint pt = m_ptCenter - mp;
	pt.x = (long)(pt.x / m_fZoom + 0.5f);
	pt.y = (long)(pt.y / m_fZoom + 0.5f);
	
	CPoint Vc((m_sizeDis.cx / 2), (m_sizeDis.cy / 2));
	
	return (Vc - pt);
}

CPoint TMap::VpToMp(const CPoint &vp)
{
	//pointMap = centerMap - (centerView - pointView) * zoom
	//centerView = sizeView / 2

	CPoint Vc((m_sizeDis.cx / 2), (m_sizeDis.cy / 2));
	CPoint pt = Vc - vp;
	pt.x = (long)(pt.x * m_fZoom + 0.5f);
	pt.y = (long)(pt.y * m_fZoom + 0.5f);

	return (m_ptCenter - pt);
}

BOOL TMap::CreateNavigate(HWND view)
{
	if (INVALID_HANDLE_VALUE == m_hBMsrc)
	{
		return FALSE;
	}
	
	m_navigate.CreateEx(
		WS_EX_WINDOWEDGE | WS_EX_TOPMOST,
		AfxRegisterWndClass(CS_NOCLOSE),
		(LPCTSTR)"navigate",
		WS_CHILD | WS_VISIBLE | WS_BORDER,
		0, 0, 0, 0,
		view,
		0);
	
	return TRUE;
}



BOOL TMap::LoadMapFromMostPicture(LPCTSTR filePath)
{
	CImage image;
	HRESULT nRet = image.Load(filePath);
	if(S_OK != nRet)
		return FALSE;

	m_hBMsrc = image.Detach();

	m_DCsrc.DeleteDC();
	m_DCsrc.CreateCompatibleDC(NULL);
	m_DCsrc.SelectObject(m_hBMsrc);

	CBitmap * pBitMap = CBitmap::FromHandle(m_hBMsrc);
	//m_ptCenter.x = bmih->biWidth / 2;
	//m_ptCenter.y = bmih->biHeight / 2;

	
	return 0;
}